#include <stdio.h>
#include <string.h>
#include <xip_bytesGeneric.h>

/* COMPATIBILIZAR */
#define WORD XIP_BYTE_WORD
#define DWORD XIP_BYTE_DWORD
#define BYTE XIP_BYTE_BYTE
/* -----------------------------------------------------
/* El deltatime de midi se guarda en un formato de datos variables.
/*
/* Una serie de bytes que tienen el bit 8 a 1 salvo el ultimo
/* Ejemplos: 0x9a 0xf1 0x0a, 0xa3 0xb3 0x01, 0x0a
/* El byte con el bit 8 a 0 es el ultimo.
/* 
/* El numero resultante es un base 128 de los bytes (quitando el bit 8) 
/* Por ejemplo si son 3 bytes, el numero resultante es :
/* 128*128*primero + 128*segundo + tercero
/* -----------------------------------------------------


/*
   -----------------------------------------------------
   Versióel Steev's Midi Library 
   Que utiliza el formato unsigned long para formatear el numero.
   -----------------------------------------------------
  ptr es el puntero a la cadena de bytes
  num es el DWORD captado
  RETORNO es el numero de bytes leidos
  si el numero de bytes leidos es >MIDI_STREAM_MAXBYTES, significa que es un error
 */

#define MIDI_STREAM_MAXBYTES 5
int midiReadMaxBytes(void)
{
 return(MIDI_STREAM_MAXBYTES);
}
int midiReadVarLen(BYTE *ptr, DWORD *num,int ilen)
{
int len=0;
*num=0l;
while(1)
{  
  if (len >= MIDI_STREAM_MAXBYTES)
   return(-1);  
  if (len >= ilen)
   return(-1);   
  (*num)=((*num) << 7)+ ( *ptr & 0x7f);  
  len++;
  if ((*ptr & 0x80 )==0) break;
  ptr++;
} 
if (xip_bytesEndian()==XIP_BYTE_BIG_ENDIAN)
   *num=xip_bytesEndianChangeLong(*num);
return(len);
}

/*
cestado=0 --> que se comienza a leer
cestado=1 --> que se estáeyendo
// intentaremos quitar este cestado.
ptr, es el byte que leemos
*len son los bytes leidos. Es un digamos retorno
num es el numero leido

RETORNO 0 hay mas bytes
RETORNO 1 finalizado, solo en ese momento, num tieme significado.
RETORNO -1 demasiados bytes
¿Cuantos bytes permitimos?
LA ESPECIFICACION MIDI DICE QUE PUEDE HABER COMO MAXIMO 5 BYTES Y QUE EL NUMERO HA DE CABER EN 4 BYTES
*/





char midiStreamReadVarLen(BYTE ptr, char cestado,DWORD *num,int *ilen)
{

char retorno=0;


if (cestado==0)
 {
   *num=0;
   *ilen=0;
   return(0); // no se lee el ptr.
 }
if (*ilen >= MIDI_STREAM_MAXBYTES)
   return(-1); 
*num=((*num) << 7) + ( ptr & 0x7f);
(*ilen)++;
if ((ptr & 0x80 )==0) 
{
  if (xip_bytesEndian()==XIP_BYTE_BIG_ENDIAN)
    *num=xip_bytesEndianChangeLong(*num);

  return(1);
}
return(0);
}


int midiWriteVarLen(DWORD num,BYTE *ptr)
{
register DWORD valor;
int i;
int len=0;

unsigned char c;
//primer byte
if (num==0l) 
 {ptr[0]=0; return(1);}
 
if (xip_bytesEndian()==XIP_BYTE_BIG_ENDIAN)
   num=xip_bytesEndianChangeLong(num);
for (i=0;i<MIDI_STREAM_MAXBYTES;i++)
{
 valor=(num>>7*(4-i)) & 0x7f;

 if (len != 0 || valor != 0) 
    {
     ptr[len ]=valor;
     if (i<MIDI_STREAM_MAXBYTES-1)
       ptr[len] |=0x80;
     len++;
	}
//      printf("byte<%d> <%x>\n",i+1,valor);
}
return(len);
}

